<template>
  <div>
    <p>按下录音：会使用浏览器 mediaRecorder 录音并上传到后端进行转写与摘要</p>
    <button @click="start" :disabled="recording">开始录音</button>
    <button @click="stop" :disabled="!recording">停止并上传</button>
    <p v-if="status">状态：{{ status }}</p>
    <!-- 可选：增加录音时长显示 -->
    <p v-if="recording">时长: {{ duration }} 秒</p>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  data() {
    return {
      recording: false,
      mediaRecorder: null,
      mediaStream: null, // 新增：保存媒体流引用
      chunks: [],
      status: '',
      duration: 0,
      durationInterval: null
    }
  },
  methods: {
    async start() {
      this.chunks = []
      this.status = '请求麦克风权限...'

      try {
        // 获取媒体流，并禁用降噪和回声消除以避免移动端系统音量变小的问题[3](@ref)
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: {
            noiseSuppression: false, // 新增：禁用降噪
            echoCancellation: false // 新增：禁用回声消除
          }
        })
        this.mediaStream = stream // 保存流引用以便后续释放

        // 优先选择浏览器支持的、更适合后端处理的格式[2,3](@ref)
        const options = this.getRecorderOptions()
        this.mediaRecorder = new MediaRecorder(stream, options)

        this.mediaRecorder.ondataavailable = (e) => {
          if (e.data.size > 0) {
            this.chunks.push(e.data)
          }
        }
        this.mediaRecorder.onstop = this.onStop

        this.mediaRecorder.start()
        this.recording = true
        this.status = '录音中...'
        this.duration = 0
        // 开始计时
        this.durationInterval = setInterval(() => {
          this.duration++
        }, 1000)

      } catch (error) {
        console.error('获取麦克风失败:', error)
        this.handleMediaError(error)
      }
    },

    async stop() {
      if (!this.mediaRecorder || this.mediaRecorder.state === 'inactive') {
        return
      }
      this.status = '停止录音，准备上传...'
      this.mediaRecorder.stop()
      this.recording = false
      // 停止计时器
      if (this.durationInterval) {
        clearInterval(this.durationInterval)
        this.durationInterval = null
      }
      // 释放媒体流资源[1](@ref)
      this.releaseMediaStream()
    },

    async onStop() {
      const mimeType = this.mediaRecorder?.mimeType || 'audio/webm'
      const blob = new Blob(this.chunks, { type: mimeType })

      console.log('音频Blob信息:', {
        size: blob.size,
        type: blob.type,
        chunksLength: this.chunks.length
      })

      const form = new FormData()
      const fileExt = mimeType.includes('wav') ? 'wav' : 'webm'
      form.append('file', new File([blob], `recording.${fileExt}`, { type: mimeType }))



      this.status = '上传中...'
      try {
        const resp = await axios.post('http://localhost:8080/api/note/upload', form, {
          //headers: { 'Content-Type': 'multipart/form-data' },
          timeout: 30000 // 30秒超时
        })
        this.$emit('result', resp.data)
        this.status = '上传及处理完成'
      } catch (e) {
        console.error('上传失败详情:', e)
        if (e.response) {
          // 服务器返回了错误状态码
          console.error('响应数据:', e.response.data)
          console.error('响应状态:', e.response.status)
          this.status = `上传失败 (${e.response.status}): ${e.response.data}`
        } else if (e.request) {
          // 请求已发出但没有收到响应
          console.error('无响应:', e.request)
          this.status = '网络错误：无法连接到服务器'
        } else {
          // 其他错误
          this.status = '错误：' + e.message
        }
        this.$emit('error', e)
      }
    },

    // 新增：获取最适合的录制参数
    getRecorderOptions() {
      const preferWav = 'audio/wav'
      const fallbackWebm = 'audio/webm'

      // 检查浏览器是否支持WAV格式[2](@ref)
      if (MediaRecorder.isTypeSupported(preferWav)) {
        return { mimeType: preferWav }
      } else if (MediaRecorder.isTypeSupported(fallbackWebm)) {
        return { mimeType: fallbackWebm }
      }
      // 如果都不支持，不指定mimeType，使用浏览器默认值
      return {}
    },

    // 新增：处理媒体错误
    handleMediaError(error) {
      this.status = '错误：'
      switch (error.name) {
        case 'NotAllowedError':
          this.status += '麦克风权限被拒绝。请检查浏览器设置。'
          break
        case 'NotFoundError':
          this.status += '未找到麦克风设备。'
          break
        case 'NotSupportedError':
          this.status += '浏览器不支持录音功能。'
          break
        default:
          this.status += '无法访问麦克风。'
      }
      this.$emit('error', error)
    },

    // 新增：释放媒体资源
    releaseMediaStream() {
      if (this.mediaStream) {
        this.mediaStream.getTracks().forEach(track => track.stop())
        this.mediaStream = null
      }
    }
  },
  beforeUnmount() {
    // 组件销毁前确保资源被释放
    this.releaseMediaStream()
    if (this.durationInterval) {
      clearInterval(this.durationInterval)
    }
  }
}
</script>
